
package com.wy2cloud.jpa;

import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 系统名称 xx平台
 * 工程名称 wy2-cloud
 * 创建时间 2017/8/1 14:47
 *
 * @author admin
 * @since 1.8
 */
public class BaseJpaRepositoryImpl <T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseJpaRepository<T, ID> {
    private final EntityManager entityManager;
    public BaseJpaRepositoryImpl(Class<T> domainClass, EntityManager em) {
        super(domainClass, em);
        this.entityManager=em;
    }

    public <D> List<D> findListBySql(String sql, Object... values) {
        final Query query = entityManager.createNativeQuery(sql);
        if(values!=null&&values.length>0){
            int i=0;
            for(Object obj:values){
                i++;
                query.setParameter(i,obj);
            }
        }
        List<D> resultList =query.getResultList();
        return resultList;
    }

    public List<Map<String, Object>> findListMapBySql(String sql, Object... values) {
        final Query query = entityManager.createNativeQuery(sql);
        //,Map.class
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if(values!=null&&values.length>0){
            int i=0;
            for(Object obj:values){
                i++;
                query.setParameter(i,obj);
            }
        }
        List<Map<String, Object>> resultList =query.getResultList();
        return resultList;
    }

    public <D> Page<D> findPageBySql(String sql, Pageable pageable, Object... values) {
        final Query query = entityManager.createNativeQuery(sql);
        if(values!=null&&values.length>0){
            int i=0;
            for(Object obj:values){
                i++;
                query.setParameter(i,obj);
            }
        }

        final int pageIndex = pageable.getPageNumber() == 0 ? 1 : pageable.getPageNumber();
        final int pageSize = pageable.getPageSize();
        int total= query.getResultList().size();
        int start=(pageIndex-1)*pageSize;
        if(start<total && pageSize>0){
            query.setFirstResult(start);
            query.setMaxResults(pageSize);
        }

        List<D> resultList =query.getResultList();
        return new PageImpl<D>(resultList,pageable,total);
    }

    public Page<Map<String, Object>> findPageForMapBySql(String sql, Pageable pageable, Object... values) {
        final Query query = entityManager.createNativeQuery(sql);
        //,Map.class
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if(values!=null&&values.length>0){
            int i=0;
            for(Object obj:values){
                i++;
                query.setParameter(i,obj);
            }
        }
        final int pageIndex = pageable.getPageNumber() == 0 ? 1 : pageable.getPageNumber();
        final int pageSize = pageable.getPageSize();
        int total= query.getResultList().size();
        int start=(pageIndex-1)*pageSize;
        if(start<total && pageSize>0){
            query.setFirstResult(start);
            query.setMaxResults(pageSize);
        }
        List<Map<String, Object>> resultList =query.getResultList();
        return new PageImpl<Map<String, Object>>(resultList,pageable,total);
    }
}